#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const srcEntities = require('./src/entities');
const testEntities = require('./test/entities');
const util = require('./util');

const argv = require('yargs')
  .usage('Usage: $0 <command> [options]')
  .command('module', 'Create es6 business and test code for special module')
  .example('$0 module -n module1', 'Create module1')
  .alias('n', 'name')
  .nargs('n', 1)
  .describe('name', 'Module name')
  .demandOption(['n'])
  .help('h')
  .alias('h', 'help')
  .argv;

const moduleName = argv.name;
const srcPath = path.join(__dirname, '../src/pages/', moduleName);
const testPath = path.join(__dirname, '../test/pages/', moduleName);

// create file
function createFile(modulePath, folder, file) {
  const options = { encoding: 'UTF-8' };

  fs.readFile(path.join(__dirname, file.template), options, (err, data) => {
    if (err) {
      return;
    }

    let filePath = null;
    if (folder && folder.name) {
      filePath = path.join(modulePath, folder.name, file.name);
    } else {
      filePath = path.join(modulePath, file.name);
    }
    
    const result = util.replace(data, moduleName);
    fs.appendFileSync(filePath, result, options);
  });
}

// create module
function createModule(modulePath, entities) {
  try {
    fs.mkdirSync(modulePath);

    // create folder
    entities.folders.forEach((folder) => {
      // create folder
      fs.mkdirSync(path.join(modulePath, folder.name));

      // create files
      if (folder.files && folder.files.length > 0) {
        folder.files.forEach((file) => {
          createFile(modulePath, folder, file);
        });
      }
    });
  } catch (err) {
    if (err.code === 'EEXIST') {
      console.log(err.path, 'this folder already exists!');
      return;
    }

    throw err;
  }
}

try {
  // create module files in src folder
  createModule(srcPath, srcEntities);

  // create module files in test folder
  createModule(testPath, testEntities);

  console.log('create module success!');
} catch (e) {
  throw e;
}
